#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "estructuras.h"
#include "constantes.h"
#include "listas.h"
#include "CSCAN.h"

int opuesto(int a)
{
	switch(a)
	{
		case 0:
		return 0;
		case 1:
		return 1;
		case 2:
		return 2;
		case 3:
		return 3;
		case 4:
		return 4;
		case 5:
		return 0;
		case 6:
		return 1;
		case 7:
		return 2;
		case 8:
		return 3;
		case 9:
		return 4;
		default:
		return -1;

	}
}

void ordenarArray(int arr[5])
{
   int ordenado=0;
   int aux,i,len;

   len = 5;

   while( !ordenado )
   {
      ordenado=1;
      for( i=0; i<len-1; i++ )
      {
         if( arr[i+1]<arr[i] )
         {
            aux=arr[i];
            arr[i]=arr[i+1];
            arr[i+1]=aux;
            ordenado=0;
         }
      }
   }
}

struct ListaIDdescriptors* maximo(struct ListaIDdescriptors *lista){

	struct ListaIDdescriptors *max;
	
	
	max=lista;

	while(lista!=NULL){

		if(lista->sector > max->sector)
			max=lista;
			
		lista=lista->Sgt;
	
	}

	
	return max;

}


struct ListaIDdescriptors * minimo(struct ListaIDdescriptors *lista){

	struct ListaIDdescriptors *min, *aux;
	
	min=lista;
	aux=lista;

	while(min!=NULL){
		if(lista->sector < min->sector)
			min=lista;	
		lista=lista->Sgt;
	}
	
	
	return min;

}

int ordenarLista(struct ListaIDdescriptors **lista)
{ 
	struct ListaIDdescriptors *primero, *segundo, *tercero, *temp; 
	
	if (*lista==NULL) 
	{ 
		printf("\nLa cola esta vacia.\n"); 
		return 1;
	} 
	else 
	{ 
		primero = *lista; 
		
		if(primero->Sgt != NULL)
		{
			segundo = primero->Sgt; 
		
			if (primero->sector > segundo->sector) 
			{ 
				*lista = segundo; 
				primero->Sgt = segundo->Sgt; 
				segundo->Sgt = primero; 
				
				return 0;
			} 
			
			if(segundo->Sgt != NULL)
			{
				tercero = segundo->Sgt; 
			
				while(tercero != NULL)
				{
					if (segundo->sector > tercero->sector) 
					{ 
						primero->Sgt = tercero; 
						segundo->Sgt = tercero->Sgt; 
						tercero->Sgt = segundo;

						return 0;
					} 
					
					primero = segundo; 
					segundo = tercero; 
					tercero = tercero->Sgt; 
					
				}
				return 1;
			}
			return 1;
			
		}
		return 1;
			
		
	}
	
	return 0;
} 

int ordenarListaDesc(struct ListaIDdescriptors **lista)
{ 
	struct ListaIDdescriptors *primero, *segundo, *tercero, *temp; 
	
	if (*lista==NULL) 
	{ 
		printf("La cola esta vacia.\n"); 
		return 1;
	} 
	else 
	{ 
		primero = *lista; 
		
		if(primero->Sgt != NULL)
		{
			segundo = primero->Sgt; 
		
			if (primero->sector <= segundo->sector) 
			{ 
				*lista = segundo; 
				primero->Sgt = segundo->Sgt; 
				segundo->Sgt = primero; 
				return 0;
			} 
			
			if(segundo->Sgt != NULL)
			{
				tercero = segundo->Sgt; 
			
				while(tercero != NULL)
				{
					if (segundo->sector <= tercero->sector) 
					{ 
						primero->Sgt = tercero; 
						segundo->Sgt = tercero->Sgt; 
						tercero->Sgt = segundo;

						return 0;
					} 
					
					primero = segundo; 
					segundo = tercero; 
					tercero = tercero->Sgt; 
					
				}
				return 1;
			}
			return 0;
			
		}
		return 1;
	}
	return 0;
} 




/*** Le pasas un array con hasta 5 sectores (los no validos van en -1) y te lo devuelve ordenado segun C-SCAN ***/
int ordenarArrayCSCAN(int sectores[5], int segundo) {

	int auxSectores[5];
	int a,i;
	int pos = -1;
	int masCercano = -1;

	ordenarArray(sectores); 


	a=0;
	while(a<5)
	{
		auxSectores[a] = sectores[a];
		a++;
	}

	/*** separo entre la posicion segundo ***/
	
	a = 0;
	while(a < 5 )
	{
		if(auxSectores[a]>=segundo)
		{
			if(auxSectores[a] < masCercano || masCercano == -1)
			{
				masCercano = auxSectores[a];
				pos = a;
			}
		}

		a++;
	}

	if(pos == -1)
	{
		return 0;
	}

	for(i = 0; i<5; i++)
	{
		sectores[i] = -1;
	}

	a=0;
	for(i = 0; i<5; i++)
	{
		if(auxSectores[opuesto(pos)] != -1)
		{
			sectores[a] = auxSectores[opuesto(pos)];
			a++;
			
		}
		pos++;
	}

	return 0;

}

/*** Le pasas un array con hasta 5 sectores (los no validos van en -1) y te lo devuelve ordenado segun SCAN ***/

int ordenarArraySCAN(int sectores[5], int segundo) { 

	int auxSectores[5];
	int a,i;
	int pos = -1;
	int masCercano = -1;

	ordenarArray(sectores);   /*Ordena el array de sectores de menor a mayor*/

	
	/*Copia el array de sectores en auxsectores*/
	a=0;
	while(a<5)
	{
		auxSectores[a] = sectores[a];
		a++;
	}

	a = 0;
	
	while(a < 5 )
	{
		if(auxSectores[a]>=segundo)
		{
			if(auxSectores[a] < masCercano || masCercano == -1)
			{
				masCercano = auxSectores[a];
				pos = a;
			}
		}

		a++;
	}

	if(pos == -1)
	{
		return 0;
	}

	for(i = 0; i<5; i++)
	{
		sectores[i] = -1;
	}

	a=0;
	
	for(i = pos; i<5; i++)
	{
		sectores[a] = auxSectores[i];
		a++;
	}

	for(i = (pos-1);i>=0; i--)
	{
		sectores[a] = auxSectores[i];
		a++;
	}
	
	
	return 0;

}


/*** Le pasas un array con hasta 5 sectores (los no validos van en -1) y te lo devuelve ordenado segun SCAN ***/
int ordenarListaSCAN(struct ListaIDdescriptors **lista, struct ListaIDdescriptors **lista_ult,int cabezal) {

	struct ListaIDdescriptors* ListaDeIDPedidos=NULL;
	struct ListaIDdescriptors* ListaDeIDPedidos_ult=NULL;
	
	struct ListaIDdescriptors* Listaaux2;
	struct ListaIDdescriptors* Listaaux3;
	

	struct ListaIDdescriptors* ListaMenores=NULL;
	struct ListaIDdescriptors* ListaMenores_ult=NULL;
	struct ListaIDdescriptors* ListaMayores=NULL;
	struct ListaIDdescriptors* ListaMayores_ult=NULL;
	struct ListaIDdescriptors* Listaaux=NULL;
	
	
	struct ListaIDdescriptors* comodin;
	    
	int ret = 0;
	while(ret == 0)
		ret = ordenarLista(&(*lista));
		
	Listaaux2=*lista;
	if(Listaaux2->Sgt != NULL)
	{
		while(Listaaux2->Sgt != NULL)
			Listaaux2= Listaaux2->Sgt;
		*lista_ult= Listaaux2;
	}
	else
		*lista_ult=*lista;
		
		
	Listaaux=*lista;
	while(Listaaux != NULL)
	{
		if(Listaaux->sector < cabezal)
		{
			comodin=malloc(sizeof(struct ListaIDdescriptors));
			memcpy(comodin, Listaaux, sizeof(struct ListaIDdescriptors));
			AgregarAColaDePedidosADisco(&comodin,&ListaMenores,&ListaMenores_ult);	
		}
		
		if(Listaaux->sector >= cabezal)
		{
			comodin=malloc(sizeof(struct ListaIDdescriptors));
			memcpy(comodin, Listaaux, sizeof(struct ListaIDdescriptors));
			AgregarAColaDePedidosADisco(&comodin,&ListaMayores,&ListaMayores_ult);	
		}
		
		Listaaux=Listaaux->Sgt;
	}	


	/*********/
	ret = 0;
	while(ret == 0)
		ret = ordenarListaDesc(&(ListaMenores));
	

	if(Listaaux2==  NULL){	
		Listaaux2=ListaMenores;
		if(Listaaux2->Sgt != NULL)
		{
			while(Listaaux2->Sgt != NULL)
				Listaaux2= Listaaux2->Sgt;
			ListaMenores_ult= Listaaux2;
		}
		else{
			ListaMenores_ult=ListaMenores;
		}
	}
	/*********/

	Listaaux2=ListaMayores;
	while(Listaaux2 != NULL)
	{	
		comodin=malloc(sizeof(struct ListaIDdescriptors));
		memcpy(comodin, Listaaux2, sizeof(struct ListaIDdescriptors));
		AgregarAColaDePedidosADisco(&comodin,&ListaDeIDPedidos,&ListaDeIDPedidos_ult);	
		
		Listaaux2=Listaaux2->Sgt;
	}
	
		
	Listaaux3=ListaMenores;
	while(Listaaux3 != NULL)
	{	
		comodin=malloc(sizeof(struct ListaIDdescriptors));
		memcpy(comodin, Listaaux3, sizeof(struct ListaIDdescriptors));
		AgregarAColaDePedidosADisco(&comodin,&ListaDeIDPedidos,&ListaDeIDPedidos_ult);	
		
		Listaaux3=Listaaux3->Sgt;
	}
	
	*lista = ListaDeIDPedidos;
	*lista_ult = ListaDeIDPedidos_ult;
	
	return 0;
	
	
}



/*** Le pasas un array con hasta 5 sectores (los no validos van en -1) y te lo devuelve ordenado segun C-SCAN ***/
int ordenarListaCSCAN(struct ListaIDdescriptors **lista, struct ListaIDdescriptors **lista_ult,int cabezal) {

	struct ListaIDdescriptors* ListaDeIDPedidos=NULL;
	struct ListaIDdescriptors* ListaDeIDPedidos_ult=NULL;
	
	struct ListaIDdescriptors* Listaaux2;
	struct ListaIDdescriptors* Listaaux3;
	
	
	struct ListaIDdescriptors* ListaMenores=NULL;
	struct ListaIDdescriptors* ListaMenores_ult=NULL;
	struct ListaIDdescriptors* ListaMayores=NULL;
	struct ListaIDdescriptors* ListaMayores_ult=NULL;
	struct ListaIDdescriptors* Listaaux=NULL;
	
	
	struct ListaIDdescriptors* comodin;
	    
	int ret = 0;
	while(ret == 0)
		ret = ordenarLista(&(*lista));
		
	Listaaux2=*lista;
	if(Listaaux2->Sgt != NULL)
	{
		while(Listaaux2->Sgt != NULL)
			Listaaux2= Listaaux2->Sgt;
		*lista_ult= Listaaux2;
	}
	else
		*lista_ult=*lista;
		
		
	Listaaux=*lista;
	while(Listaaux != NULL)
	{
		if(Listaaux->sector < cabezal)
		{
			comodin=malloc(sizeof(struct ListaIDdescriptors));
			memcpy(comodin, Listaaux, sizeof(struct ListaIDdescriptors));
			AgregarAColaDePedidosADisco(&comodin,&ListaMenores,&ListaMenores_ult);	
		}
		
		if(Listaaux->sector >= cabezal)
		{
			comodin=malloc(sizeof(struct ListaIDdescriptors));
			memcpy(comodin, Listaaux, sizeof(struct ListaIDdescriptors));
			AgregarAColaDePedidosADisco(&comodin,&ListaMayores,&ListaMayores_ult);	
		}
		
		Listaaux=Listaaux->Sgt;
	}
	
	/*
	ret = 0;
	while(ret == 0)
		ret = ordenarListaDesc(&(ListaMenores));
	
	Listaaux2=ListaMenores;
	if(Listaaux2->Sgt != NULL)
	{
		while(Listaaux2->Sgt != NULL)
			Listaaux2= Listaaux2->Sgt;
		ListaMenores_ult= Listaaux2;
	}
	else
		ListaMenores_ult=ListaMenores;
		*/
		
	Listaaux2=ListaMayores;
	while(Listaaux2 != NULL)
	{	
		comodin=malloc(sizeof(struct ListaIDdescriptors));
		memcpy(comodin, Listaaux2, sizeof(struct ListaIDdescriptors));
		AgregarAColaDePedidosADisco(&comodin,&ListaDeIDPedidos,&ListaDeIDPedidos_ult);	
		
		Listaaux2=Listaaux2->Sgt;
	}
	
		
	Listaaux3=ListaMenores;
	while(Listaaux3 != NULL)
	{	
		comodin=malloc(sizeof(struct ListaIDdescriptors));
		memcpy(comodin, Listaaux3, sizeof(struct ListaIDdescriptors));
		AgregarAColaDePedidosADisco(&comodin,&ListaDeIDPedidos,&ListaDeIDPedidos_ult);	
		
		Listaaux3=Listaaux3->Sgt;
	}
	
	*lista = ListaDeIDPedidos;
	*lista_ult = ListaDeIDPedidos_ult;
	
	return 0;

}


